/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_MEMORY_CACHE_INTERCEPTOR_OH_H
#define IMAGE_KNIFE_C_MEMORY_CACHE_INTERCEPTOR_OH_H

#include "interceptor.h"
#include "imageknife_request.h"
#include "memory_cache.h"
#include "imageknife_internal.h"
#include "imageknife_data_napi.h"
#include <sstream>

namespace ImageKnifeC {
class MemoryCacheInterceptorOH : public MemoryCacheInterceptor {
public:
    MemoryCacheInterceptorOH()
    {
        name = "Default MemoryCacheInterceptor";
    }

    bool Resolve(std::shared_ptr<ImageKnifeTask> task) override
    {
        if (task->product.cacheType == CacheTaskType::WRITE) {
            return Write(task);
        } else if (task->product.cacheType == CacheTaskType::READ){
            bool readResult = Read(task);
//             task->request->imageKnifeData.timeInfo.memoryCheckEndTime = ImageKnifeDataNapi::GetTimestamp();
            return readResult;
        }

        return false;
    }

private:
    bool Read(std::shared_ptr<ImageKnifeTask> task)
    {
//         task->request->imageKnifeData.timeInfo.memoryCheckStartTime = ImageKnifeDataNapi::GetTimestamp();
        std::shared_ptr<ImageKnifeOption> imageKnifeOption = task->GetImageKnifeRequest()->GetImageKnifeOption();
        CacheKeyGenerator::MemoryKeyParams memoryKeyParams;
        memoryKeyParams.imageSource = task->GetImageSource();
        memoryKeyParams.type = task->GetImageRequestType();
        memoryKeyParams.isAnimator = task->IsAnimator();
        memoryKeyParams.signature = task->GetImageKnifeRequest()->GetImageKnifeOption()->signature;
        std::string memoryKey = ImageKnife::GetInstance().GetCacheKeyGenerator()->GenerateMemoryKey(memoryKeyParams);
        if (MemoryCache::GetInstance()->Contains(memoryKey)) {
            task->product.imageDataCache = MemoryCache::GetInstance()->Get(memoryKey);
            if (task->product.imageDataCache == nullptr) {
                task->EchoError("Empty ImageData");
                return false;
            }
            return true;
        }

        if (imageKnifeOption->loadSrc.GetType() == DataType::PIXELMAP) {
            OH_PixelmapNative *pixelMap = nullptr;
            if (imageKnifeOption->loadSrc.GetPixelMap(pixelMap)) {
                task->product.imageDataCache = std::make_shared<ImageDataCacheInternal>(pixelMap);
                return true;
            }
            return false;
        }
        return false;
    }

    bool Write(std::shared_ptr<ImageKnifeTask> task)
    {
        CacheKeyGenerator::MemoryKeyParams memoryKeyParams;
        memoryKeyParams.imageSource = task->GetImageSource();
        memoryKeyParams.type = task->GetImageRequestType();
        memoryKeyParams.isAnimator = task->IsAnimator();
        memoryKeyParams.signature = task->GetImageKnifeRequest()->GetImageKnifeOption()->signature;
        std::string memoryKey = ImageKnife::GetInstance().GetCacheKeyGenerator()->GenerateMemoryKey(memoryKeyParams);

        if (task->product.imageDataCache != nullptr) {
            MemoryCache::GetInstance()->Put(memoryKey, task->product.imageDataCache);
            return true;
        } else {
            task->EchoError("Try to Cache Empty ImageData");
            return false;
        }
    }
};

};

#endif // IMAGE_KNIFE_C_MEMORY_CACHE_INTERCEPTOR_OH_H
